import time
import uuid
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
import structlog
from datetime import datetime
import sys

logger = structlog.get_logger()


class LoggingMiddleware(BaseHTTPMiddleware):
    def __init__(self, app):
        super().__init__(app)
        print("LoggingMiddleware 初始化完成")

    async def dispatch(self, request: Request, call_next):
        # 确保每个请求都能被记录
        request_id = str(uuid.uuid4())
        start_time = time.time()

        print("=" * 60)
        print(f"LoggingMiddleware: 开始处理请求,时间: {datetime.now().strftime('%H:%M:%S.%f')[:-3]},路径: {request.url.path},方法: {request.method},客户端IP: {request.client.host if request.client else 'unknown'},请求ID: {request_id}")

        # 立即刷新输出
        sys.stdout.flush()

        # 将请求ID添加到请求对象
        request.state.request_id = request_id

        # 获取User-Agent
        user_agent = request.headers.get("user-agent", "未知")
        print(f"User-Agent: {user_agent}")
        print("=" * 60)
        sys.stdout.flush()

        # 使用 structlog 记录请求信息
        try:
            logger.info(
                "Request started",
                request_id=request_id,
                method=request.method,
                path=request.url.path,
                query_params=str(request.query_params),
                client_ip=request.client.host if request.client else 'unknown',
                user_agent=user_agent
            )
        except Exception as e:
            print(f"structlog 记录失败: {e}")
            sys.stdout.flush()

        try:
            # 处理请求
            response = await call_next(request)

            # 计算处理时间
            process_time = time.time() - start_time

            # 🔥 请求完成调试输出
            # print("\n" + "📝" + "=" * 60)
            # print(f"📝 LoggingMiddleware: 请求完成")
            # print(f"   请求ID: {request_id}")
            # print(f"   状态码: {response.status_code}")
            # print(f"   处理时间: {process_time:.3f}s")
            # print("📝" + "=" * 60 + "\n")
            sys.stdout.flush()

            # 使用 structlog 记录响应信息
            try:
                logger.info(
                    "Request completed",
                    request_id=request_id,
                    method=request.method,
                    path=request.url.path,
                    status_code=response.status_code,
                    process_time=process_time
                )
            except Exception as e:
                print(f"📝 ❌ structlog 响应记录失败: {e}")
                sys.stdout.flush()

            # 添加请求ID到响应头
            response.headers["X-Request-ID"] = request_id

            return response

        except Exception as e:
            # 确保异常也被记录
            process_time = time.time() - start_time

            logger.error("\n" + "📝" + "=" * 60)
            logger.error(f"📝 LoggingMiddleware: 请求异常")
            logger.error(f"   请求ID: {request_id}")
            logger.error(f"   异常: {str(e)}")
            logger.error(f"   处理时间: {process_time:.3f}s")
            logger.error("📝" + "=" * 60 + "\n")
            sys.stdout.flush()

            try:
                logger.error(
                    "Request failed",
                    request_id=request_id,
                    method=request.method,
                    path=request.url.path,
                    error=str(e),
                    process_time=process_time
                )
            except Exception as log_error:
                print(f"📝 ❌ structlog 异常记录失败: {log_error}")
                sys.stdout.flush()

            # 重新抛出异常
            raise